/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */
+const Shell = imports.gi.Shell;
const St = imports.gi.St;
const Gettext_gtk20 = imports.gettext.domain('gtk20');
};
}
-_patchContainerClass(St.BoxLayout);
-_patchContainerClass(St.Table);
+// Replace @method with something that throws an error instead
+function _blockMethod(method, replacement, reason) {
+ let match = method.match(/^(.+)\.([^.]+)$/);
+ if (!match)
+ throw new Error('Bad method name "' + method + '"');
+ let proto = 'imports.gi.' + match[1] + '.prototype';
+ let property = match[2];
+
+ if (!global.set_property_mutable(proto, property, true))
+ throw new Error('Bad method name "' + method + '"');
+
+ // eval() is evil in general, but we know it's safe here since
+ // set_property_mutable() would have failed if proto was
+ // malformed.
+ let node = eval(proto);
+
+ let msg = 'Do not use "' + method + '".';
+ if (replacement)
+ msg += ' Use "' + replacement + '" instead.';
+ if (reason)
+ msg += ' (' + reason + ')';
+
+ node[property] = function() {
+ throw new Error(msg);
+ };
+
+ global.set_property_mutable(proto, property, false);
+}
function init() {
Tweener.init();
if (Gettext_gtk20.gettext('default:LTR') == 'default:RTL') {
St.Widget.set_default_direction(St.TextDirection.RTL);
}
+
+ _patchContainerClass(St.BoxLayout);
+ _patchContainerClass(St.Table);
+
+ _blockMethod('Clutter.Event.get_state', 'Shell.get_event_state',
+ 'gjs\'s handling of Clutter.ModifierType is broken. See bug 597292.');
+ _blockMethod('Gdk.Display.get_pointer', 'global.get_pointer',
+ 'gjs\'s handling of Gdk.ModifierType is broken. See bug 597292.');
+ _blockMethod('Gdk.Window.get_pointer', 'global.get_pointer',
+ 'gjs\'s handling of Gdk.ModifierType is broken. See bug 597292.');
+
+ // Now close the back door to prevent extensions from trying to
+ // abuse it. We can't actually delete it since
+ // Shell.Global.prototype itself is read-only.
+ global.set_property_mutable('imports.gi.Shell.Global.prototype', 'set_property_mutable', true);
+ Shell.Global.prototype.set_property_mutable = undefined;
}
return (GAppLaunchContext *)context;
}
+
+/**
+ * shell_global_set_property_mutable:
+ * @global: the #ShellGlobal
+ * @object: the "path" to a JS object, starting from the root object.
+ * (Eg, "global.stage" or "imports.gi.Gtk.Window.prototype")
+ * @property: a property on @object
+ * @mutable: %TRUE or %FALSE
+ *
+ * If @mutable is %TRUE, this clears the "permanent" and "readonly" flags
+ * on @property of @object. If @mutable is %FALSE, it sets them.
+ *
+ * You can use this to make it possible to modify properties that
+ * would otherwise be read-only from JavaScript.
+ *
+ * Return value: success or failure.
+ */
+gboolean
+shell_global_set_property_mutable (ShellGlobal *global,
+ const char *object,
+ const char *property,
+ gboolean mutable)
+{
+ JSContext *context = gjs_context_get_native_context (global->js_context);
+ char **parts;
+ JSObject *obj;
+ jsval val = JSVAL_VOID;
+ int i;
+ jsuint attrs;
+ JSBool found;
+
+ JS_AddRoot (context, &val);
+
+ parts = g_strsplit (object, ".", -1);
+ obj = JS_GetGlobalObject (context);
+ for (i = 0; parts[i]; i++)
+ {
+ if (!JS_GetProperty (context, obj, parts[i], &val))
+ {
+ g_strfreev (parts);
+ JS_RemoveRoot (context, &val);
+ gjs_log_exception (context, NULL);
+ return FALSE;
+ }
+ obj = JSVAL_TO_OBJECT (val);
+ }
+ g_strfreev (parts);
+
+ if (!JS_GetPropertyAttributes (context, obj, property, &attrs, &found) || !found)
+ {
+ JS_RemoveRoot (context, &val);
+ gjs_log_exception (context, NULL);
+ return FALSE;
+ }
+
+ if (mutable)
+ attrs &= ~(JSPROP_PERMANENT | JSPROP_READONLY);
+ else
+ attrs |= (JSPROP_PERMANENT | JSPROP_READONLY);
+
+ JS_SetPropertyAttributes (context, obj, property, attrs, &found);
+
+ JS_RemoveRoot (context, &val);
+ return !gjs_log_exception (context, NULL);
+}
GAppLaunchContext *shell_global_create_app_launch_context (ShellGlobal *global);
+gboolean shell_global_set_property_mutable (ShellGlobal *global,
+ const char *object,
+ const char *property,
+ gboolean mutable);
+
G_END_DECLS
#endif /* __SHELL_GLOBAL_H__ */